home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / TRIANGLE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-17  |  27.9 KB  |  1,407 lines

  1. /****************************************************************************
  2. *                triangle.c
  3. *
  4. *  This module implements primitives for triangles and smooth triangles.
  5. *
  6. *  from Persistence of Vision(tm) Ray Tracer
  7. *  Copyright 1996 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  NOTICE: This source code file is provided so that users may experiment
  10. *  with enhancements to POV-Ray and to port the software to platforms other
  11. *  than those supported by the POV-Ray Team.  There are strict rules under
  12. *  which you are permitted to use this file.  The rules are in the file
  13. *  named POVLEGAL.DOC which should be distributed with this file. If
  14. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  16. *  Forum.  The latest version of POV-Ray may be found there as well.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23.  
  24. #include "frame.h"
  25. #include "povray.h"
  26. #include "vector.h"
  27. #include "povproto.h"
  28. #include "matrices.h"
  29. #include "objects.h"
  30. #include "triangle.h"
  31.  
  32.  
  33.  
  34. /*****************************************************************************
  35. * Local preprocessor defines
  36. ******************************************************************************/
  37.  
  38. #define DEPTH_TOLERANCE 1e-6
  39.  
  40. #define max3_coordinate(x,y,z) \
  41.   ((x > y) ? ((x > z) ? X : Z) : ((y > z) ? Y : Z))
  42.  
  43.  
  44.  
  45. /*****************************************************************************
  46. * Static functions
  47. ******************************************************************************/
  48.  
  49. static void find_triangle_dominant_axis PARAMS((TRIANGLE *Triangle));
  50. static void compute_smooth_triangle  PARAMS((SMOOTH_TRIANGLE *Triangle));
  51. static int Intersect_Triangle  PARAMS((RAY *Ray, TRIANGLE *Triangle, DBL *Depth));
  52. static int All_Triangle_Intersections  PARAMS((OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack));
  53. static int Inside_Triangle  PARAMS((VECTOR IPoint, OBJECT *Object));
  54. static void Triangle_Normal  PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
  55. static void *Copy_Triangle  PARAMS((OBJECT *Object));
  56. static void Translate_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  57. static void Rotate_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  58. static void Scale_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  59. static void Transform_Triangle  PARAMS((OBJECT *Object, TRANSFORM *Trans));
  60. static void Invert_Triangle  PARAMS((OBJECT *Object));
  61. static void Smooth_Triangle_Normal  PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
  62. static void *Copy_Smooth_Triangle PARAMS((OBJECT *Object));
  63. static void Translate_Smooth_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  64. static void Rotate_Smooth_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  65. static void Scale_Smooth_Triangle  PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  66. static void Transform_Smooth_Triangle  PARAMS((OBJECT *Object, TRANSFORM *Trans));
  67. static void Invert_Smooth_Triangle  PARAMS((OBJECT *Object));
  68. static void Destroy_Triangle  PARAMS((OBJECT *Object));
  69.  
  70.  
  71.  
  72. /*****************************************************************************
  73. * Local variables
  74. ******************************************************************************/
  75.  
  76. METHODS Triangle_Methods =
  77. {
  78.   All_Triangle_Intersections,
  79.   Inside_Triangle, Triangle_Normal,
  80.   Copy_Triangle,
  81.   Translate_Triangle, Rotate_Triangle,
  82.   Scale_Triangle, Transform_Triangle, Invert_Triangle, Destroy_Triangle
  83. };
  84.  
  85. METHODS Smooth_Triangle_Methods =
  86. {
  87.   All_Triangle_Intersections,
  88.   Inside_Triangle, Smooth_Triangle_Normal,
  89.   Copy_Smooth_Triangle,
  90.   Translate_Smooth_Triangle, Rotate_Smooth_Triangle,
  91.   Scale_Smooth_Triangle, Transform_Smooth_Triangle,
  92.   Invert_Smooth_Triangle, Destroy_Triangle
  93. };
  94.  
  95.  
  96. /*****************************************************************************
  97. *
  98. * FUNCTION
  99. *
  100. *   find_triangle_dominant_axis
  101. *
  102. * INPUT
  103. *   
  104. * OUTPUT
  105. *   
  106. * RETURNS
  107. *   
  108. * AUTHOR
  109. *
  110. *   POV-Ray Team
  111. *   
  112. * DESCRIPTION
  113. *
  114. *   -
  115. *
  116. * CHANGES
  117. *
  118. *   -
  119. *
  120. ******************************************************************************/
  121.  
  122. static void find_triangle_dominant_axis(Triangle)
  123. TRIANGLE *Triangle;
  124. {
  125.   DBL x, y, z;
  126.  
  127.   x = fabs(Triangle->Normal_Vector[X]);
  128.   y = fabs(Triangle->Normal_Vector[Y]);
  129.   z = fabs(Triangle->Normal_Vector[Z]);
  130.  
  131.   Triangle->Dominant_Axis = max3_coordinate(x, y, z);
  132. }
  133.  
  134.  
  135.  
  136. /*****************************************************************************
  137. *
  138. * FUNCTION
  139. *
  140. *   compute_smooth_triangle
  141. *
  142. * INPUT
  143. *   
  144. * OUTPUT
  145. *   
  146. * RETURNS
  147. *   
  148. * AUTHOR
  149. *
  150. *   POV-Ray Team
  151. *   
  152. * DESCRIPTION
  153. *
  154. *   -
  155. *
  156. * CHANGES
  157. *
  158. *   -
  159. *
  160. ******************************************************************************/
  161.  
  162. static void compute_smooth_triangle(Triangle)
  163. SMOOTH_TRIANGLE *Triangle;
  164. {
  165.   VECTOR P3MinusP2, VTemp1, VTemp2;
  166.   DBL x, y, z, uDenominator, Proj;
  167.  
  168.   VSub(P3MinusP2, Triangle->P3, Triangle->P2);
  169.  
  170.   x = fabs(P3MinusP2[X]);
  171.   y = fabs(P3MinusP2[Y]);
  172.   z = fabs(P3MinusP2[Z]);
  173.  
  174.   Triangle->vAxis = max3_coordinate(x, y, z);
  175.  
  176.   VSub(VTemp1, Triangle->P2, Triangle->P3);
  177.  
  178.   VNormalize(VTemp1, VTemp1);
  179.  
  180.   VSub(VTemp2, Triangle->P1, Triangle->P3);
  181.  
  182.   VDot(Proj, VTemp2, VTemp1);
  183.  
  184.   VScaleEq(VTemp1, Proj);
  185.  
  186.   VSub(Triangle->Perp, VTemp1, VTemp2);
  187.  
  188.   VNormalize(Triangle->Perp, Triangle->Perp);
  189.  
  190.   VDot(uDenominator, VTemp2, Triangle->Perp);
  191.  
  192.   VInverseScaleEq(Triangle->Perp, -uDenominator);
  193. }
  194.  
  195.  
  196.  
  197. /*****************************************************************************
  198. *
  199. * FUNCTION
  200. *
  201. *   Compute_Triangle
  202. *
  203. * INPUT
  204. *   
  205. * OUTPUT
  206. *   
  207. * RETURNS
  208. *   
  209. * AUTHOR
  210. *
  211. *   POV-Ray Team
  212. *   
  213. * DESCRIPTION
  214. *
  215. *   -
  216. *
  217. * CHANGES
  218. *
  219. *   -
  220. *
  221. ******************************************************************************/
  222.  
  223. int Compute_Triangle(Triangle,Smooth)
  224. TRIANGLE *Triangle;
  225. int Smooth;
  226. {
  227.   int swap;
  228.   VECTOR V1, V2, Temp;
  229.   DBL Length;
  230.  
  231.   VSub(V1, Triangle->P1, Triangle->P2);
  232.   VSub(V2, Triangle->P3, Triangle->P2);
  233.  
  234.   VCross(Triangle->Normal_Vector, V1, V2);
  235.  
  236.   VLength(Length, Triangle->Normal_Vector);
  237.  
  238.   /* Set up a flag so we can ignore degenerate triangles */
  239.  
  240.   if (Length == 0.0)
  241.   {
  242.     Set_Flag(Triangle, DEGENERATE_FLAG);
  243.  
  244.     return(FALSE);
  245.   }
  246.  
  247.   /* Normalize the normal vector. */
  248.  
  249.   VInverseScaleEq(Triangle->Normal_Vector, Length);
  250.  
  251.   VDot(Triangle->Distance, Triangle->Normal_Vector, Triangle->P1);
  252.  
  253.   Triangle->Distance *= -1.0;
  254.  
  255.   find_triangle_dominant_axis(Triangle);
  256.  
  257.   swap = FALSE;
  258.  
  259.   switch (Triangle->Dominant_Axis)
  260.   {
  261.     case X:
  262.  
  263.       if ((Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[Z] - Triangle->P1[Z]) <
  264.           (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[Y] - Triangle->P1[Y]))
  265.       {
  266.         swap = TRUE;
  267.       }
  268.  
  269.       break;
  270.  
  271.     case Y:
  272.  
  273.       if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Z] - Triangle->P1[Z]) <
  274.           (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[X] - Triangle->P1[X]))
  275.       {
  276.         swap = TRUE;
  277.       }
  278.  
  279.       break;
  280.  
  281.     case Z:
  282.  
  283.       if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Y] - Triangle->P1[Y]) <
  284.           (Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[X] - Triangle->P1[X]))
  285.       {
  286.         swap = TRUE;
  287.       }
  288.  
  289.       break;
  290.   }
  291.  
  292.   if (swap)
  293.   {
  294.     Assign_Vector(Temp, Triangle->P2);
  295.     Assign_Vector(Triangle->P2, Triangle->P1);
  296.     Assign_Vector(Triangle->P1, Temp);
  297.  
  298.     if (Smooth)
  299.     {
  300.       Assign_Vector(Temp, ((SMOOTH_TRIANGLE *)Triangle)->N2);
  301.       Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N2, ((SMOOTH_TRIANGLE *)Triangle)->N1);
  302.       Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N1, Temp);
  303.     }
  304.   }
  305.  
  306.   if (Smooth)
  307.   {
  308.     compute_smooth_triangle((SMOOTH_TRIANGLE *)Triangle);
  309.   }
  310.  
  311.   /* Build the bounding information from the vertices. */
  312.  
  313.   Compute_Triangle_BBox(Triangle);
  314.  
  315.   return(TRUE);
  316. }
  317.  
  318.  
  319.  
  320. /*****************************************************************************
  321. *
  322. * FUNCTION
  323. *
  324. *   All_Triangle_Intersections
  325. *
  326. * INPUT
  327. *   
  328. * OUTPUT
  329. *   
  330. * RETURNS
  331. *   
  332. * AUTHOR
  333. *
  334. *   POV-Ray Team
  335. *   
  336. * DESCRIPTION
  337. *
  338. *   -
  339. *
  340. * CHANGES
  341. *
  342. *   -
  343. *
  344. ******************************************************************************/
  345.  
  346. static int All_Triangle_Intersections(Object, Ray, Depth_Stack)
  347. OBJECT *Object;
  348. RAY *Ray;
  349. ISTACK *Depth_Stack;
  350. {
  351.   DBL Depth;
  352.   VECTOR IPoint;
  353.  
  354.   if (Intersect_Triangle(Ray, (TRIANGLE *)Object, &Depth))
  355.   {
  356.     VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);
  357.  
  358.     if (Point_In_Clip(IPoint,Object->Clip))
  359.     {
  360.       push_entry(Depth,IPoint,Object,Depth_Stack);
  361.  
  362.       return(TRUE);
  363.     }
  364.   }
  365.  
  366.   return(FALSE);
  367. }
  368.  
  369.  
  370.  
  371. /*****************************************************************************
  372. *
  373. * FUNCTION
  374. *
  375. *   Intersect_Triangle
  376. *
  377. * INPUT
  378. *   
  379. * OUTPUT
  380. *   
  381. * RETURNS
  382. *   
  383. * AUTHOR
  384. *
  385. *   POV-Ray Team
  386. *   
  387. * DESCRIPTION
  388. *
  389. *   -
  390. *
  391. * CHANGES
  392. *
  393. *   -
  394. *
  395. ******************************************************************************/
  396.  
  397. static int Intersect_Triangle(Ray, Triangle, Depth)
  398. RAY *Ray;
  399. TRIANGLE *Triangle;
  400. DBL *Depth;
  401. {
  402.   DBL NormalDotOrigin, NormalDotDirection;
  403.   DBL s, t;
  404.  
  405.   Increase_Counter(stats[Ray_Triangle_Tests]);
  406.  
  407.   if (Test_Flag(Triangle, DEGENERATE_FLAG))
  408.   {
  409.     return(FALSE);
  410.   }
  411.  
  412.   VDot(NormalDotDirection, Triangle->Normal_Vector, Ray->Direction);
  413.  
  414.   if (fabs(NormalDotDirection) < EPSILON)
  415.   {
  416.     return(FALSE);
  417.   }
  418.  
  419.   VDot(NormalDotOrigin, Triangle->Normal_Vector, Ray->Initial);
  420.  
  421.   *Depth = -(Triangle->Distance + NormalDotOrigin) / NormalDotDirection;
  422.  
  423.   if ((*Depth < DEPTH_TOLERANCE) || (*Depth > Max_Distance))
  424.   {
  425.     return(FALSE);
  426.   }
  427.  
  428.   switch (Triangle->Dominant_Axis)
  429.   {
  430.     case X:
  431.  
  432.       s = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
  433.       t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
  434.  
  435.       if ((Triangle->P2[Y] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
  436.           (Triangle->P2[Z] - t) * (Triangle->P2[Y] - Triangle->P1[Y]))
  437.       {
  438.         return(FALSE);
  439.       }
  440.  
  441.       if ((Triangle->P3[Y] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
  442.           (Triangle->P3[Z] - t) * (Triangle->P3[Y] - Triangle->P2[Y]))
  443.       {
  444.         return(FALSE);
  445.       }
  446.  
  447.       if ((Triangle->P1[Y] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
  448.           (Triangle->P1[Z] - t) * (Triangle->P1[Y] - Triangle->P3[Y]))
  449.       {
  450.         return(FALSE);
  451.       }
  452.  
  453.       Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  454.  
  455.       return(TRUE);
  456.  
  457.     case Y:
  458.  
  459.       s = Ray->Initial[X] + *Depth * Ray->Direction[X];
  460.       t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
  461.  
  462.       if ((Triangle->P2[X] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
  463.           (Triangle->P2[Z] - t) * (Triangle->P2[X] - Triangle->P1[X]))
  464.       {
  465.         return(FALSE);
  466.       }
  467.  
  468.       if ((Triangle->P3[X] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
  469.           (Triangle->P3[Z] - t) * (Triangle->P3[X] - Triangle->P2[X]))
  470.       {
  471.         return(FALSE);
  472.       }
  473.  
  474.       if ((Triangle->P1[X] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
  475.           (Triangle->P1[Z] - t) * (Triangle->P1[X] - Triangle->P3[X]))
  476.       {
  477.         return(FALSE);
  478.       }
  479.  
  480.       Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  481.  
  482.       return(TRUE);
  483.  
  484.     case Z:
  485.  
  486.       s = Ray->Initial[X] + *Depth * Ray->Direction[X];
  487.       t = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
  488.  
  489.       if ((Triangle->P2[X] - s) * (Triangle->P2[Y] - Triangle->P1[Y]) <
  490.           (Triangle->P2[Y] - t) * (Triangle->P2[X] - Triangle->P1[X]))
  491.       {
  492.         return(FALSE);
  493.       }
  494.  
  495.       if ((Triangle->P3[X] - s) * (Triangle->P3[Y] - Triangle->P2[Y]) <
  496.           (Triangle->P3[Y] - t) * (Triangle->P3[X] - Triangle->P2[X]))
  497.       {
  498.         return(FALSE);
  499.       }
  500.  
  501.       if ((Triangle->P1[X] - s) * (Triangle->P1[Y] - Triangle->P3[Y]) <
  502.           (Triangle->P1[Y] - t) * (Triangle->P1[X] - Triangle->P3[X]))
  503.       {
  504.         return(FALSE);
  505.       }
  506.  
  507.       Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  508.  
  509.       return(TRUE);
  510.   }
  511.  
  512.   return(FALSE);
  513. }
  514.  
  515.  
  516.  
  517. /*****************************************************************************
  518. *
  519. * FUNCTION
  520. *
  521. *   Inside_Triangle
  522. *
  523. * INPUT
  524. *   
  525. * OUTPUT
  526. *   
  527. * RETURNS
  528. *   
  529. * AUTHOR
  530. *
  531. *   POV-Ray Team
  532. *   
  533. * DESCRIPTION
  534. *
  535. *   -
  536. *
  537. * CHANGES
  538. *
  539. *   -
  540. *
  541. ******************************************************************************/
  542.  
  543. static int Inside_Triangle(IPoint, Object)
  544. VECTOR IPoint;
  545. OBJECT *Object;
  546. {
  547.   return(FALSE);
  548. }
  549.  
  550.  
  551.  
  552. /*****************************************************************************
  553. *
  554. * FUNCTION
  555. *
  556. *   Triangle_Normal
  557. *
  558. * INPUT
  559. *   
  560. * OUTPUT
  561. *   
  562. * RETURNS
  563. *   
  564. * AUTHOR
  565. *
  566. *   POV-Ray Team
  567. *   
  568. * DESCRIPTION
  569. *
  570. *   -
  571. *
  572. * CHANGES
  573. *
  574. *   -
  575. *
  576. ******************************************************************************/
  577.  
  578. static void Triangle_Normal(Result, Object, Inter)
  579. OBJECT *Object;
  580. VECTOR Result;
  581. INTERSECTION *Inter;
  582. {
  583.   Assign_Vector(Result, ((TRIANGLE *)Object)->Normal_Vector);
  584. }
  585.  
  586.  
  587.  
  588. /*****************************************************************************
  589. *
  590. * FUNCTION
  591. *
  592. *   Smooth_Triangle_Normal
  593. *
  594. * INPUT
  595. *   
  596. * OUTPUT
  597. *   
  598. * RETURNS
  599. *   
  600. * AUTHOR
  601. *
  602. *   POV-Ray Team
  603. *   
  604. * DESCRIPTION
  605. *
  606. *   Calculate the Phong-interpolated vector within the triangle
  607. *   at the given intersection point. The math for this is a bit
  608. *   bizarre:
  609. *
  610. *      -         P1
  611. *      |        /|\ \
  612. *      |       / |Perp\
  613. *      |      /  V  \   \
  614. *      |     /   |    \   \
  615. *    u |    /____|_____PI___\
  616. *      |   /     |       \    \
  617. *      -  P2-----|--------|----P3
  618. *                Pbase    PIntersect
  619. *          |-------------------|
  620. *                         v
  621. *
  622. *   Triangle->Perp is a unit vector from P1 to Pbase. We calculate
  623. *
  624. *   u = (PI - P1) DOT Perp / ((P3 - P1) DOT Perp).
  625. *
  626. *   We then calculate where the line from P1 to PI intersects the line P2 to P3:
  627. *   PIntersect = (PI - P1)/u.
  628. *
  629. *   We really only need one coordinate of PIntersect.  We then calculate v as:
  630. *
  631. *        v = PIntersect[X] / (P3[X] - P2[X])
  632. *   or   v = PIntersect[Y] / (P3[Y] - P2[Y])
  633. *   or   v = PIntersect[Z] / (P3[Z] - P2[Z])
  634. *
  635. *   depending on which calculation will give us the best answers.
  636. *
  637. *   Once we have u and v, we can perform the normal interpolation as:
  638. *
  639. *     NTemp1 = N1 + u(N2 - N1);
  640. *     NTemp2 = N1 + u(N3 - N1);
  641. *     Result = normalize (NTemp1 + v(NTemp2 - NTemp1))
  642. *
  643. *   As always, any values which are constant for the triangle are cached
  644. *   in the triangle.
  645. *
  646. * CHANGES
  647. *
  648. *   -
  649. *
  650. ******************************************************************************/
  651.  
  652. static void Smooth_Triangle_Normal(Result, Object, Inter)
  653. OBJECT *Object;
  654. VECTOR Result;
  655. INTERSECTION *Inter;
  656. {
  657.   int Axis;
  658.   DBL u, v;
  659.   VECTOR PIMinusP1;
  660.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  661.  
  662.   VSub(PIMinusP1, Inter->IPoint, Triangle->P1);
  663.  
  664.   VDot(u, PIMinusP1, Triangle->Perp);
  665.  
  666.   if (u < EPSILON)
  667.   {
  668.     Assign_Vector(Result, Triangle->N1);
  669.     return;
  670.   }
  671.  
  672.   Axis = Triangle->vAxis;
  673.  
  674.   v = (PIMinusP1[Axis] / u + Triangle->P1[Axis] - Triangle->P2[Axis]) / (Triangle->P3[Axis] - Triangle->P2[Axis]);
  675.  
  676.   /* This is faster. [DB 8/94] */
  677.  
  678.   Result[X] = Triangle->N1[X] + u * (Triangle->N2[X] - Triangle->N1[X] + v * (Triangle->N3[X] - Triangle->N2[X]));
  679.   Result[Y] = Triangle->N1[Y] + u * (Triangle->N2[Y] - Triangle->N1[Y] + v * (Triangle->N3[Y] - Triangle->N2[Y]));
  680.   Result[Z] = Triangle->N1[Z] + u * (Triangle->N2[Z] - Triangle->N1[Z] + v * (Triangle->N3[Z] - Triangle->N2[Z]));
  681.  
  682.   VNormalize(Result, Result);
  683. }
  684.  
  685.  
  686.  
  687. /*****************************************************************************
  688. *
  689. * FUNCTION
  690. *
  691. *   Translate_Triangle
  692. *
  693. * INPUT
  694. *   
  695. * OUTPUT
  696. *   
  697. * RETURNS
  698. *   
  699. * AUTHOR
  700. *
  701. *   POV-Ray Team
  702. *   
  703. * DESCRIPTION
  704. *
  705. *   -
  706. *
  707. * CHANGES
  708. *
  709. *   -
  710. *
  711. ******************************************************************************/
  712.  
  713. static void Translate_Triangle(Object, Vector, Trans)
  714. OBJECT *Object;
  715. VECTOR Vector;
  716. TRANSFORM *Trans;
  717. {
  718.   TRIANGLE *Triangle = (TRIANGLE *)Object;
  719.   VECTOR Translation;
  720.  
  721.   if (!Test_Flag(Triangle, DEGENERATE_FLAG))
  722.   {
  723.     VEvaluate(Translation, Triangle->Normal_Vector, Vector);
  724.  
  725.     Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
  726.  
  727.     VAddEq(Triangle->P1, Vector);
  728.     VAddEq(Triangle->P2, Vector);
  729.     VAddEq(Triangle->P3, Vector);
  730.  
  731.     Compute_Triangle(Triangle, FALSE);
  732.   }
  733. }
  734.  
  735.  
  736.  
  737. /*****************************************************************************
  738. *
  739. * FUNCTION
  740. *
  741. *   Rotate_Triangle
  742. *
  743. * INPUT
  744. *
  745. * OUTPUT
  746. *
  747. * RETURNS
  748. *
  749. * AUTHOR
  750. *
  751. *   POV-Ray Team
  752. *
  753. * DESCRIPTION
  754. *
  755. *   -
  756. *
  757. * CHANGES
  758. *
  759. *   -
  760. *
  761. ******************************************************************************/
  762.  
  763. static void Rotate_Triangle(Object, Vector, Trans)
  764. OBJECT *Object;
  765. VECTOR Vector;
  766. TRANSFORM *Trans;
  767. {
  768.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  769.   {
  770.     Transform_Triangle(Object, Trans);
  771.   }
  772. }
  773.  
  774.  
  775.  
  776. /*****************************************************************************
  777. *
  778. * FUNCTION
  779. *
  780. *   Scale_Triangle
  781. *
  782. * INPUT
  783. *
  784. * OUTPUT
  785. *
  786. * RETURNS
  787. *
  788. * AUTHOR
  789. *
  790. *   POV-Ray Team
  791. *
  792. * DESCRIPTION
  793. *
  794. *   -
  795. *
  796. * CHANGES
  797. *
  798. *   -
  799. *
  800. ******************************************************************************/
  801.  
  802. static void Scale_Triangle(Object, Vector, Trans)
  803. OBJECT *Object;
  804. VECTOR Vector;
  805. TRANSFORM *Trans;
  806. {
  807.   DBL Length;
  808.   TRIANGLE *Triangle = (TRIANGLE *)Object;
  809.  
  810.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  811.   {
  812.     Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
  813.     Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
  814.     Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
  815.  
  816.     VLength(Length, Triangle->Normal_Vector);
  817.  
  818.     VInverseScaleEq(Triangle->Normal_Vector, Length);
  819.  
  820.     Triangle->Distance /= Length;
  821.  
  822.     VEvaluateEq(Triangle->P1, Vector);
  823.     VEvaluateEq(Triangle->P2, Vector);
  824.     VEvaluateEq(Triangle->P3, Vector);
  825.  
  826.     Compute_Triangle(Triangle, FALSE);
  827.   }
  828. }
  829.  
  830.  
  831.  
  832. /*****************************************************************************
  833. *
  834. * FUNCTION
  835. *
  836. *   Transfrom_Triangle
  837. *
  838. * INPUT
  839. *   
  840. * OUTPUT
  841. *   
  842. * RETURNS
  843. *
  844. * AUTHOR
  845. *
  846. *   POV-Ray Team
  847. *
  848. * DESCRIPTION
  849. *
  850. *   -
  851. *
  852. * CHANGES
  853. *
  854. *   -
  855. *
  856. ******************************************************************************/
  857.  
  858. static void Transform_Triangle(Object, Trans)
  859. OBJECT *Object;
  860. TRANSFORM *Trans;
  861. {
  862.   TRIANGLE *Triangle = (TRIANGLE *)Object;
  863.  
  864.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  865.   {
  866.     MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
  867.     MTransPoint(Triangle->P1, Triangle->P1, Trans);
  868.     MTransPoint(Triangle->P2, Triangle->P2, Trans);
  869.     MTransPoint(Triangle->P3, Triangle->P3, Trans);
  870.  
  871.     Compute_Triangle(Triangle, FALSE);
  872.   }
  873. }
  874.  
  875.  
  876.  
  877. /*****************************************************************************
  878. *
  879. * FUNCTION
  880. *
  881. *   Invert_Triangle
  882. *
  883. * INPUT
  884. *   
  885. * OUTPUT
  886. *   
  887. * RETURNS
  888. *   
  889. * AUTHOR
  890. *
  891. *   POV-Ray Team
  892. *   
  893. * DESCRIPTION
  894. *
  895. *   -
  896. *
  897. * CHANGES
  898. *
  899. *   -
  900. *
  901. ******************************************************************************/
  902.  
  903. static void Invert_Triangle(Object)
  904. OBJECT *Object;
  905. {
  906. }
  907.  
  908.  
  909.  
  910. /*****************************************************************************
  911. *
  912. * FUNCTION
  913. *
  914. *   Create_Triangle
  915. *
  916. * INPUT
  917. *   
  918. * OUTPUT
  919. *   
  920. * RETURNS
  921. *   
  922. * AUTHOR
  923. *
  924. *   POV-Ray Team
  925. *   
  926. * DESCRIPTION
  927. *
  928. *   -
  929. *
  930. * CHANGES
  931. *
  932. *   -
  933. *
  934. ******************************************************************************/
  935.  
  936. TRIANGLE *Create_Triangle()
  937. {
  938.   TRIANGLE *New;
  939.  
  940.   New = (TRIANGLE *)POV_MALLOC(sizeof(TRIANGLE), "triangle");
  941.  
  942.   INIT_OBJECT_FIELDS(New,TRIANGLE_OBJECT,&Triangle_Methods)
  943.  
  944.   Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
  945.  
  946.   New->Distance = 0.0;
  947.  
  948.   Make_Vector(New->P1, 0.0, 0.0, 0.0);
  949.   Make_Vector(New->P2, 1.0, 0.0, 0.0);
  950.   Make_Vector(New->P3, 0.0, 1.0, 0.0);
  951.  
  952.   /*
  953.    * NOTE: Dominant_Axis is computed when Parse_Triangle calls
  954.    * Compute_Triangle. vAxis is used only for smooth triangles.
  955.    */
  956.  
  957.   return(New);
  958. }
  959.  
  960.  
  961.  
  962. /*****************************************************************************
  963. *
  964. * FUNCTION
  965. *
  966. *   Copy_Triangle
  967. *
  968. * INPUT
  969. *   
  970. * OUTPUT
  971. *   
  972. * RETURNS
  973. *   
  974. * AUTHOR
  975. *
  976. *   POV-Ray Team
  977. *   
  978. * DESCRIPTION
  979. *
  980. *   -
  981. *
  982. * CHANGES
  983. *
  984. *   -
  985. *
  986. ******************************************************************************/
  987.  
  988. static void *Copy_Triangle(Object)
  989. OBJECT *Object;
  990. {
  991.   TRIANGLE *New;
  992.  
  993.   New = Create_Triangle();
  994.  
  995.   *New = *((TRIANGLE *)Object);
  996.  
  997.   return(New);
  998. }
  999.  
  1000.  
  1001.  
  1002. /*****************************************************************************
  1003. *
  1004. * FUNCTION
  1005. *
  1006. *   Destroy_Triangle
  1007. *
  1008. * INPUT
  1009. *   
  1010. * OUTPUT
  1011. *   
  1012. * RETURNS
  1013. *   
  1014. * AUTHOR
  1015. *
  1016. *   POV-Ray Team
  1017. *   
  1018. * DESCRIPTION
  1019. *
  1020. *   -
  1021. *
  1022. * CHANGES
  1023. *
  1024. *   -
  1025. *
  1026. ******************************************************************************/
  1027.  
  1028. static void Destroy_Triangle(Object)
  1029. OBJECT *Object;
  1030. {
  1031.   POV_FREE (Object);
  1032. }
  1033.  
  1034.  
  1035.  
  1036. /*****************************************************************************
  1037. *
  1038. * FUNCTION
  1039. *
  1040. *   Translate_Smooth_Triangle
  1041. *
  1042. * INPUT
  1043. *   
  1044. * OUTPUT
  1045. *   
  1046. * RETURNS
  1047. *   
  1048. * AUTHOR
  1049. *
  1050. *   POV-Ray Team
  1051. *   
  1052. * DESCRIPTION
  1053. *
  1054. *   -
  1055. *
  1056. * CHANGES
  1057. *
  1058. *   -
  1059. *
  1060. ******************************************************************************/
  1061.  
  1062. static void Translate_Smooth_Triangle(Object, Vector, Trans)
  1063. OBJECT *Object;
  1064. VECTOR Vector;
  1065. TRANSFORM *Trans;
  1066. {
  1067.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  1068.   VECTOR Translation;
  1069.  
  1070.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1071.   {
  1072.     VEvaluate(Translation, Triangle->Normal_Vector, Vector);
  1073.  
  1074.     Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
  1075.  
  1076.     VAddEq(Triangle->P1, Vector);
  1077.     VAddEq(Triangle->P2, Vector);
  1078.     VAddEq(Triangle->P3, Vector);
  1079.  
  1080.     Compute_Triangle((TRIANGLE *)Triangle, TRUE);
  1081.   }
  1082. }
  1083.  
  1084.  
  1085.  
  1086. /*****************************************************************************
  1087. *
  1088. * FUNCTION
  1089. *
  1090. *   Rotate_Smooth_Triangle
  1091. *
  1092. * INPUT
  1093. *   
  1094. * OUTPUT
  1095. *   
  1096. * RETURNS
  1097. *   
  1098. * AUTHOR
  1099. *
  1100. *   POV-Ray Team
  1101. *
  1102. * DESCRIPTION
  1103. *
  1104. *   -
  1105. *
  1106. * CHANGES
  1107. *
  1108. *   -
  1109. *
  1110. ******************************************************************************/
  1111.  
  1112. static void Rotate_Smooth_Triangle(Object, Vector, Trans)
  1113. OBJECT *Object;
  1114. VECTOR Vector;
  1115. TRANSFORM *Trans;
  1116. {
  1117.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1118.   {
  1119.     Transform_Smooth_Triangle(Object, Trans);
  1120.   }
  1121. }
  1122.  
  1123.  
  1124.  
  1125. /*****************************************************************************
  1126. *
  1127. * FUNCTION
  1128. *
  1129. *   Scale_Smooth_Triangle
  1130. *
  1131. * INPUT
  1132. *   
  1133. * OUTPUT
  1134. *   
  1135. * RETURNS
  1136. *   
  1137. * AUTHOR
  1138. *
  1139. *   POV-Ray Team
  1140. *   
  1141. * DESCRIPTION
  1142. *
  1143. *   -
  1144. *
  1145. * CHANGES
  1146. *
  1147. *   -
  1148. *
  1149. ******************************************************************************/
  1150.  
  1151. static void Scale_Smooth_Triangle(Object, Vector, Trans)
  1152. OBJECT *Object;
  1153. VECTOR Vector;
  1154. TRANSFORM *Trans;
  1155. {
  1156.   DBL Length;
  1157.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  1158.  
  1159.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1160.   {
  1161.     Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
  1162.     Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
  1163.     Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
  1164.  
  1165.     VLength(Length, Triangle->Normal_Vector);
  1166.     VScaleEq(Triangle->Normal_Vector, 1.0 / Length);
  1167.     Triangle->Distance /= Length;
  1168.  
  1169.     VEvaluateEq(Triangle->P1, Vector);
  1170.     VEvaluateEq(Triangle->P2, Vector);
  1171.     VEvaluateEq(Triangle->P3, Vector);
  1172.  
  1173.     Compute_Triangle((TRIANGLE *)Triangle,TRUE);
  1174.   }
  1175. }
  1176.  
  1177.  
  1178.  
  1179. /*****************************************************************************
  1180. *
  1181. * FUNCTION
  1182. *
  1183. *   Transform_Smooth_Triangle
  1184. *
  1185. * INPUT
  1186. *   
  1187. * OUTPUT
  1188. *   
  1189. * RETURNS
  1190. *   
  1191. * AUTHOR
  1192. *
  1193. *   POV-Ray Team
  1194. *   
  1195. * DESCRIPTION
  1196. *
  1197. *   -
  1198. *
  1199. * CHANGES
  1200. *
  1201. *   -
  1202. *
  1203. ******************************************************************************/
  1204.  
  1205. static void Transform_Smooth_Triangle(Object, Trans)
  1206. OBJECT *Object;
  1207. TRANSFORM *Trans;
  1208. {
  1209.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  1210.  
  1211.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1212.   {
  1213.     MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
  1214.     MTransPoint(Triangle->P1, Triangle->P1, Trans);
  1215.     MTransPoint(Triangle->P2, Triangle->P2, Trans);
  1216.     MTransPoint(Triangle->P3, Triangle->P3, Trans);
  1217.     MTransPoint(Triangle->N1, Triangle->N1, Trans);
  1218.     MTransPoint(Triangle->N2, Triangle->N2, Trans);
  1219.     MTransPoint(Triangle->N3, Triangle->N3, Trans);
  1220.  
  1221.     Compute_Triangle((TRIANGLE *)Triangle, TRUE);
  1222.   }
  1223. }
  1224.  
  1225.  
  1226.  
  1227. /*****************************************************************************
  1228. *
  1229. * FUNCTION
  1230. *
  1231. *   Invert_Smooth_Triangle
  1232. *
  1233. * INPUT
  1234. *   
  1235. * OUTPUT
  1236. *   
  1237. * RETURNS
  1238. *   
  1239. * AUTHOR
  1240. *
  1241. *   POV-Ray Team
  1242. *   
  1243. * DESCRIPTION
  1244. *
  1245. *   -
  1246. *
  1247. * CHANGES
  1248. *
  1249. *   -
  1250. *
  1251. ******************************************************************************/
  1252.  
  1253. static void Invert_Smooth_Triangle(Object)
  1254. OBJECT *Object;
  1255. {
  1256. }
  1257.  
  1258.  
  1259.  
  1260. /*****************************************************************************
  1261. *
  1262. * FUNCTION
  1263. *
  1264. *   Create_Smooth_Triangle
  1265. *
  1266. * INPUT
  1267. *   
  1268. * OUTPUT
  1269. *   
  1270. * RETURNS
  1271. *   
  1272. * AUTHOR
  1273. *
  1274. *   POV-Ray Team
  1275. *   
  1276. * DESCRIPTION
  1277. *
  1278. *   -
  1279. *
  1280. * CHANGES
  1281. *
  1282. *   -
  1283. *
  1284. ******************************************************************************/
  1285.  
  1286. SMOOTH_TRIANGLE *Create_Smooth_Triangle()
  1287. {
  1288.   SMOOTH_TRIANGLE *New;
  1289.  
  1290.   New = (SMOOTH_TRIANGLE *)POV_MALLOC(sizeof(SMOOTH_TRIANGLE), "smooth triangle");
  1291.  
  1292.   INIT_OBJECT_FIELDS(New,SMOOTH_TRIANGLE_OBJECT,&Smooth_Triangle_Methods)
  1293.  
  1294.   Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
  1295.  
  1296.   New->Distance = 0.0;
  1297.  
  1298.   Make_Vector(New->P1, 0.0, 0.0, 0.0);
  1299.   Make_Vector(New->P2, 1.0, 0.0, 0.0);
  1300.   Make_Vector(New->P3, 0.0, 1.0, 0.0);
  1301.   Make_Vector(New->N1, 0.0, 1.0, 0.0);
  1302.   Make_Vector(New->N2, 0.0, 1.0, 0.0);
  1303.   Make_Vector(New->N3, 0.0, 1.0, 0.0);
  1304.  
  1305.   /*
  1306.    * NOTE: Dominant_Axis and vAxis are computed when
  1307.    * Parse_Triangle calls Compute_Triangle.
  1308.    */
  1309.  
  1310.   return(New);
  1311. }
  1312.  
  1313.  
  1314.  
  1315. /*****************************************************************************
  1316. *
  1317. * FUNCTION
  1318. *
  1319. *   Copy_Smooth_Triangle
  1320. *
  1321. * INPUT
  1322. *   
  1323. * OUTPUT
  1324. *   
  1325. * RETURNS
  1326. *   
  1327. * AUTHOR
  1328. *
  1329. *   POV-Ray Team
  1330. *   
  1331. * DESCRIPTION
  1332. *
  1333. *   -
  1334. *
  1335. * CHANGES
  1336. *
  1337. *   -
  1338. *
  1339. ******************************************************************************/
  1340.  
  1341. static void *Copy_Smooth_Triangle(Object)
  1342. OBJECT *Object;
  1343. {
  1344.   SMOOTH_TRIANGLE *New;
  1345.  
  1346.   New = Create_Smooth_Triangle();
  1347.  
  1348.   *New = *((SMOOTH_TRIANGLE *)Object);
  1349.  
  1350.   return(New);
  1351. }
  1352.  
  1353.  
  1354.  
  1355. /*****************************************************************************
  1356. *
  1357. * FUNCTION
  1358. *
  1359. *   Compute_Triangle_BBox
  1360. *
  1361. * INPUT
  1362. *
  1363. *   Triangle - Triangle
  1364. *   
  1365. * OUTPUT
  1366. *
  1367. *   Triangle
  1368. *   
  1369. * RETURNS
  1370. *   
  1371. * AUTHOR
  1372. *
  1373. *   Dieter Bayer
  1374. *   
  1375. * DESCRIPTION
  1376. *
  1377. *   Calculate the bounding box of a triangle.
  1378. *
  1379. * CHANGES
  1380. *
  1381. *   Aug 1994 : Creation.
  1382. *
  1383. ******************************************************************************/
  1384.  
  1385. void Compute_Triangle_BBox(Triangle)
  1386. TRIANGLE *Triangle;
  1387. {
  1388.   VECTOR Min, Max, Epsilon;
  1389.  
  1390.   Make_Vector(Epsilon, EPSILON, EPSILON, EPSILON);
  1391.  
  1392.   Min[X] = min3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
  1393.   Min[Y] = min3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
  1394.   Min[Z] = min3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
  1395.  
  1396.   Max[X] = max3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
  1397.   Max[Y] = max3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
  1398.   Max[Z] = max3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
  1399.  
  1400.   VSubEq(Min, Epsilon);
  1401.   VAddEq(Max, Epsilon);
  1402.  
  1403.   Make_BBox_from_min_max(Triangle->BBox, Min, Max);
  1404. }
  1405.  
  1406.  
  1407.